package manager;

import graphic.window.MainWindow;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;

/**
 * This class acts as controller, which decides when the window will be redrawn,
 * how often timer will tick etc.
 * 
 * @author Tomas Zima
 */
public abstract class Controller implements Runnable, ActionListener
{	
	/**
	 * Constructor.
	 * Set some background processes.
	 * 
	 * @param void
	 */
	public Controller()
	{
		mainWindow	= MainWindow.getInstance();				// The only window in game
		timer		= new Timer(BASIC_TIMER_TICK, this);	// Basic timer
		
		timer.start();
	}
	
	/**
	 * This method starts infinity redrawing process.
	 * It should be called after everything is prepared for next redraw.
	 * 
	 * @param void
	 * @return void
	 */
	public void start()
	{
		Thread t = new Thread(this);
		t.start();		
	}
	
	/**
	 * Infinity loop for redraw.
	 * It waits until the last redraw is done and redraws again.
	 * 
	 * @param void
	 * @return void
	 */
	@Override
	public void run()
	{
		// Redraw as fast as possible
		// (maximal fps)		
		while(true)
		{
			redraw();

			try
			{
				Thread.sleep(100);
			} catch (InterruptedException interruptedException)
			{
				//
			}

			/*
			 * This will be used after all components will be changed to
			 * use timer.*/

			/*// wait until redraw is done
			while (true)
			{
				if (isDrawingDone())
				{
					break;
				}
			}*/
		}
	}
	
	/**
	 * Timer event handler.
	 * 
	 * @param ActionEvent [e]
	 * @return void
	 */
	@Override
	public void actionPerformed(ActionEvent e)
	{
		this.onTimerEvent();
	}
	
	/**
	 * Returns tick of timer.
	 * 
	 * @param void
	 * @return int
	 */
	protected int getBasicTimerTick()
	{
		return this.BASIC_TIMER_TICK;
	}
	
	// Methods in manager class (event handlers)
	protected abstract void		redraw();			// Called when redraw is requested
	protected abstract boolean	isDrawingDone();	// Checking, if next redraw is possible
	protected abstract void		onTimerEvent();		// Called after each timer tick
	
	// Workaround needed to successful run of application
	protected	MainWindow		mainWindow;			// Raw access to main window (shouldn't be used much)
	private		Timer			timer;				// Instance of timer
	
	private final int			BASIC_TIMER_TICK = 5;	// Period of timer in miliseconds
}
